package cn.com.cifi.mars.service.impl;

import cn.com.cifi.mars.bean.dto.MymContractDto;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.IsSplitEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.entity.MymRooms;
import cn.com.cifi.mars.entity.PriceValueOrg;
import cn.com.cifi.mars.entity.common.SysDictionary;
import cn.com.cifi.mars.mapper.mars.MymRoomsMapper;
import cn.com.cifi.mars.mapper.mars.PriceVersionMapper;
import cn.com.cifi.mars.mapper.mars.SysDictionaryMapper;
import cn.com.cifi.mars.service.*;
import cn.com.cifi.mars.util.UUIDUtils;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * （明源）房间信息流水表 服务实现类
 * </p>
 *
 * @author yyd
 * @since 2019-09-25
 */
@Service
public class MymRoomsServiceImpl extends ServiceImpl<MymRoomsMapper, MymRooms> implements MymRoomsService {

    @Autowired
    private MymRoomsMapper mymRoomsMapper;

    @Autowired
    private SysDictionaryMapper sysDictionaryMapper;

    @Autowired
    private MymService mymService;

    @Autowired
    private SysNoticeService sysNoticeService;

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private PriceVersionMapper priceVersionMapper;

    @Autowired
    private PriceVersionValueOrgService priceVersionValueOrgService;

    @Autowired
    private MymRoomsService mymRoomsService;

    private static final Logger logger = LoggerFactory.getLogger(MymRoomsServiceImpl.class);


    @Override
    public List<MymRooms> selectNewestWarPlanByFid(String projectFid) {
        return mymRoomsMapper.selectNewestWarPlanByFid(projectFid);
    }

    @Override
    public List<MymRooms> selectNewestWarPlanByFids(List projectFids) {
        return mymRoomsMapper.selectNewestWarPlanByFids(projectFids);
    }

    //收集房源包
    @Override
    public Map<String, Map> collectHouse(String projectFid, List<String> parkingBuildCodes, String market, LocalDateTime now) {
        Map<String, Map> resultMap = new HashMap();
        //根据分期id查询（明源）房间信息流水表
        List<MymRooms> rooms = mymRoomsMapper.selectNewestWarPlanByFid(projectFid);

        //查询补差
        Map<String, MymContractDto> bcMap = new HashMap();
        List<MymContractDto> mymContractDtos = mymService.selectNewestContractsByProjectFid(projectFid);
        if(CollectionUtils.isNotEmpty(mymContractDtos)){
            for (MymContractDto mymContractDto : mymContractDtos){
                bcMap.put(mymContractDto.getRoomGUID().toLowerCase(), mymContractDto);
            }
        }

        //查询面积段信息
        List<SysDictionary> codes = sysDictionaryMapper.selectDictionaryByType(Arrays.asList("area_segmenta"));

        Map<String, PriceValueOrg> soldParkingMap = new HashMap<String, PriceValueOrg>();//已售车位
        Map<String, PriceValueOrg> notSoldParkingOrgMap = new HashMap<String, PriceValueOrg>();//已定价未售车位
        Map<String, Map<String, PriceValueOrg>> houseOrgMap = new HashMap<String, Map<String, PriceValueOrg>>();//已售面积段
        Map<String, BigDecimal> areaMap = new HashMap();//楼栋下总面积
        Map<String, Integer> numMap = new HashMap();//楼栋下总套数
        if (CollectionUtils.isNotEmpty(rooms)){
            for (MymRooms room : rooms){
                int isHouse = 0;//是房源还是车位, 0:房源 ,1:车位
                int isSold = IsDeleteEnum.NO.getKey();//是否已售, 0:未售, 1:已售
                //对应mdm_group_bld表的bld_prd_id楼栋Id
                String bldPrdId = room.getBldPrdId();//楼栋id
                //传过来的车位的楼栋id判断这个房间表 是车位还是房源(房间)
                if(StringUtils.isNotEmpty(bldPrdId) && parkingBuildCodes.contains(bldPrdId)){//是车位
                    isHouse = 1;
                }

                String status = room.getStatus();
                if(status.equals("签约")){//已售
                    isSold = IsDeleteEnum.YES.getKey();
                }

                MymContractDto mymContractDto = bcMap.get(room.getRoomGUID().toLowerCase());

                if(isHouse == 0){//房源
                	//实测建筑面积, sc=实测 ,ys=预售 ,bld=楼栋
                	//如果实测建筑面积为空,取预售建筑面积
                    BigDecimal roomSaleArea = room.getScBldArea();
                    if(roomSaleArea == null || roomSaleArea.compareTo(BigDecimal.ZERO) == 0){
                        roomSaleArea = room.getYsBldArea();//预售建筑面积
                    }
                    if (roomSaleArea == null){
                        roomSaleArea = BigDecimal.ZERO;
                    }

                    BigDecimal totalRoomSaleArea = areaMap.get(bldPrdId);//总可售面积
                    if(totalRoomSaleArea != null){
                    	//有数据后,每次的楼栋面积相加
                        totalRoomSaleArea = totalRoomSaleArea.add(roomSaleArea).setScale(4, BigDecimal.ROUND_HALF_UP);
                    }else{
                    	//第一次是=实测建筑面积or预售建筑面积
                        totalRoomSaleArea = roomSaleArea;
                    }
                    //把楼栋的总可售面积放到这个楼栋下面
                    areaMap.put(room.getBldPrdId(), totalRoomSaleArea);
                    //获取这个房间的楼栋数量 第一次进来是1,第二次++
                    Integer totalRoomNum = numMap.get(bldPrdId);
                    if (totalRoomNum != null){
                        totalRoomNum ++;
                    }else{
                        totalRoomNum = 1;
                    }
                    //最后放到这个楼栋总套数map里面去
                    numMap.put(room.getBldPrdId(), totalRoomNum);

                    //拆分面积段
                    for(SysDictionary dic : codes){
                        String dictValue = dic.getDictValue();

                        String[] split = dictValue.split("-");
                        Integer start = Integer.valueOf(split[0]);
                        Integer end = Integer.valueOf(split[1]);
                        if(roomSaleArea.compareTo(new BigDecimal(start)) >= 0 && roomSaleArea.compareTo(new BigDecimal(end)) < 0){

                            Map<String, PriceValueOrg> priceValueOrgMap = houseOrgMap.get(bldPrdId);
                            if(CollectionUtils.isNotEmpty(priceValueOrgMap)){
                                PriceValueOrg priceValueOrg = priceValueOrgMap.get(dictValue);
                                if(priceValueOrg != null){
                                    BigDecimal saleArea = priceValueOrg.getSaleArea();
                                    Integer roomNum = priceValueOrg.getNum();
                                    //套数/车位数, 有数据进来 房源套数为++
                                    priceValueOrg.setNum(roomNum++);
                                    //新的可售面积=本次的(实测or预测面积)+上次的可售面积
                                    priceValueOrg.setSaleArea(roomSaleArea.add(saleArea).setScale(4, BigDecimal.ROUND_HALF_UP));

                                    if(isSold == IsDeleteEnum.YES.getKey()){
                                        BigDecimal price = new BigDecimal(0);
                                        if(mymContractDto != null){
                                            BigDecimal cjRmbTotal = mymContractDto.getCjRmbTotal()==null?new BigDecimal(0):mymContractDto.getCjRmbTotal();
                                            BigDecimal bcTotal = mymContractDto.getBcTotal()==null?new BigDecimal(0):mymContractDto.getBcTotal();
                                            price = cjRmbTotal.add(bcTotal).setScale(4, BigDecimal.ROUND_HALF_UP);
                                        }
                                        priceValueOrg.setPrice(priceValueOrg.getPrice().add(price).setScale(4, BigDecimal.ROUND_HALF_UP));
                                        priceValueOrg.setPriceSold(priceValueOrg.getPrice().add(price).setScale(4, BigDecimal.ROUND_HALF_UP));
                                    }else{
                                        BigDecimal price = priceValueOrg.getPrice().add(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal()).setScale(4, BigDecimal.ROUND_HALF_UP);
                                        //新的低总价(底价总价)=房间表的底价总价+上次的底价总价
                                        priceValueOrg.setPrice(price);
                                    }
                                }else{
                                	//把循环出来的房间信息,去拆分面积段,第一次拆分好的面积段信息放到这个版本详情实体去,例如80-90这个面积段
                                    priceValueOrg = createFristNotSaleAreaPartOrg(now, room, roomSaleArea, dictValue, market, isSold, mymContractDto);
                                }
                                //把对应的这个面积段的实体放进map
                                priceValueOrgMap.put(dictValue, priceValueOrg);
                            }else{
                                priceValueOrgMap = new HashMap<String, PriceValueOrg>();
                                PriceValueOrg priceValueOrg = createFristNotSaleAreaPartOrg(now, room, roomSaleArea, dictValue, market, isSold, mymContractDto);

                                priceValueOrgMap.put(dictValue, priceValueOrg);
                            }

                            houseOrgMap.put(bldPrdId, priceValueOrgMap);
                            break;
                        }
                    }
                }else if(isHouse == 1 ){//车位
                    if(isSold == IsDeleteEnum.NO.getKey()){//已定价未售
                    	//获取已定价未售车位中是否存在这个车位楼栋id信息
                        PriceValueOrg org = notSoldParkingOrgMap.get(bldPrdId);
                        if(org != null){
                            Integer num = org.getNum();
                            num++;
                            //如果车位存在 车位数+1
                            org.setNum(num);
                            BigDecimal price = org.getPrice().add(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal()).setScale(4, BigDecimal.ROUND_HALF_UP);
                            //把每次的底价总价相加就是最终的底价总价
                            org.setPrice(price);
                            //均价=总的底价总价/总的车位数;
                            org.setAveragePriceParking(bigDecimalDIV(price, new BigDecimal(num)));
                        }else{
                            org = new PriceValueOrg();
                            org.setId(UUIDUtils.create());
                            //房源 组团 分期 楼栋 车位 类型信息
                            org.setType(OrgTypeEunm.ORG_NOT_SALE_PACKAGE.getKey());
                            org.setOrgCode(OrgTypeEunm.ORG_NOT_SALE_PACKAGE.getKey());
                            org.setOrgName(OrgTypeEunm.ORG_NOT_SALE_PACKAGE.getValue());
                            // 是否已供(0.否 1.是)
                            org.setIsSupply(IsDeleteEnum.YES.getKey());
                            //是否已售(0.否 1.是),当前是未售=否
                            org.setIsSale(IsDeleteEnum.NO.getKey());
                            //套数/车位数,当前是车位那么就是车位数 第一次进来默认1
                            org.setNum(1);

                            //底价总价
                            org.setPrice(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal());
                            //均价=总的底价总价/总的车位数;第一次进来就是/1=本身
                            org.setAveragePriceParking(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal());

                            //是否可拆分 第一次进来不能拆分
                            org.setIsSplit(IsSplitEnum.NO.getKey());
                            org.setIsDelete(IsDeleteEnum.NO.getKey());
                            org.setCreateTime(now);
                        }
                        //最后把当前的楼栋Id和版本详细放到 ,已定价未售车位map中
                        notSoldParkingOrgMap.put(bldPrdId, org);
                    }else {//已定价已售车位
                        PriceValueOrg org = soldParkingMap.get(bldPrdId);
                        if(org != null){
                        	//存在车位数+1
                            Integer num = org.getNum();
                            org.setNum(num++);

                            BigDecimal price = new BigDecimal(0);
                            if(mymContractDto != null){
                                BigDecimal cjRmbTotal = mymContractDto.getCjRmbTotal()==null?new BigDecimal(0):mymContractDto.getCjRmbTotal();
                                BigDecimal bcTotal = mymContractDto.getBcTotal()==null?new BigDecimal(0):mymContractDto.getBcTotal();
                                price = cjRmbTotal.add(bcTotal).setScale(4, BigDecimal.ROUND_HALF_UP);
                            }
                            org.setPrice(org.getPrice().add(price).setScale(4, BigDecimal.ROUND_HALF_UP));
                            org.setPriceSold(org.getPrice().add(price).setScale(4, BigDecimal.ROUND_HALF_UP));

                            org.setAveragePriceParking(bigDecimalDIV(price, new BigDecimal(num)));
                        }else{
                        	//第一次进来
                            org = new PriceValueOrg();
                            org.setId(UUIDUtils.create());
                            org.setType(OrgTypeEunm.ORG_SALE_PACKAGE.getKey());
                            org.setOrgCode(OrgTypeEunm.ORG_SALE_PACKAGE.getKey());
                            org.setOrgName(OrgTypeEunm.ORG_SALE_PACKAGE.getValue());
                            org.setIsSupply(IsDeleteEnum.YES.getKey());
                            org.setIsSale(IsDeleteEnum.YES.getKey());
                            org.setNum(1);

                            BigDecimal price = new BigDecimal(0);
                            if(mymContractDto != null){
                                BigDecimal cjRmbTotal = mymContractDto.getCjRmbTotal()==null?new BigDecimal(0):mymContractDto.getCjRmbTotal();
                                BigDecimal bcTotal = mymContractDto.getBcTotal()==null?new BigDecimal(0):mymContractDto.getBcTotal();
                                price = cjRmbTotal.add(bcTotal).setScale(4, BigDecimal.ROUND_HALF_UP);
                            }
                            org.setPrice(price);
                            org.setPriceSold(price);
                            org.setAveragePriceParking(price);

                            org.setIsSplit(IsSplitEnum.NO.getKey());
                            org.setIsDelete(IsDeleteEnum.NO.getKey());
                            org.setCreateTime(now);
                        }

                        soldParkingMap.put(bldPrdId, org);
                    }
                }
            }
        }

        resultMap.put("soldParkingMap", soldParkingMap);
        resultMap.put("notSoldParkingOrgMap", notSoldParkingOrgMap);
        resultMap.put("houseOrgMap", houseOrgMap);
        resultMap.put("areaMap", areaMap);
        resultMap.put("numMap", numMap);

        return resultMap;
    }


    @Override
    @Transactional
    public void saveRooms(List<MymRooms> dataList) {
        mymRoomsService.saveBatch(dataList);
    }


   /* private PriceValueOrg createFristSaleAreaPartOrg(LocalDateTime now, MymRooms room, BigDecimal roomSaleArea, String dictValue) {
        PriceValueOrg priceValueOrg;
        priceValueOrg = new PriceValueOrg();
        priceValueOrg.setId(UUIDUtils.create());
        priceValueOrg.setIsSale(1);
        priceValueOrg.setType(OrgTypeEunm.ORG_HOUSE_PACKAGE.getKey());
        priceValueOrg.setAreaPart(dictValue);
        priceValueOrg.setOrgName(dictValue);
        priceValueOrg.setSaleArea(roomSaleArea);
        priceValueOrg.setNum(1);
        priceValueOrg.setPrice(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal());
        priceValueOrg.setAveragePrice(bigDecimalDIV(room.getDjTotal(), roomSaleArea));
        priceValueOrg.setAveragePriceHouse(bigDecimalDIV(room.getDjTotal(), roomSaleArea));
        priceValueOrg.setAveragePriceParking(bigDecimalDIV(room.getDjTotal(), roomSaleArea));
        priceValueOrg.setIsDelete(IsDeleteEnum.NO.getKey());
        priceValueOrg.setCreateTime(now);
        return priceValueOrg;
    }*/

    private PriceValueOrg createFristNotSaleAreaPartOrg(LocalDateTime now, MymRooms room, BigDecimal roomSaleArea, String dictValue, String market, int isSold,MymContractDto mymContractDto) {
        PriceValueOrg priceValueOrg = new PriceValueOrg();
        priceValueOrg.setId(UUIDUtils.create());
        priceValueOrg.setType(OrgTypeEunm.ORG_HOUSE_PACKAGE.getKey());
        //面积段
        priceValueOrg.setAreaPart(dictValue);
        priceValueOrg.setOrgCode(OrgTypeEunm.ORG_HOUSE_PACKAGE.getKey());
        priceValueOrg.setOrgName(dictValue);
        //套数/车位数 第一次进来 房源套数为1
        priceValueOrg.setNum(1);

        //可售面积=实测或者预测建筑面积(传过来的)
        priceValueOrg.setSaleArea(roomSaleArea);

        if(isSold == IsDeleteEnum.YES.getKey()){
            //成交总价
            BigDecimal price = new BigDecimal(0);
            if(mymContractDto != null){
                BigDecimal cjRmbTotal = mymContractDto.getCjRmbTotal()==null?new BigDecimal(0):mymContractDto.getCjRmbTotal();
                BigDecimal bcTotal = mymContractDto.getBcTotal()==null?new BigDecimal(0):mymContractDto.getBcTotal();
                price = cjRmbTotal.add(bcTotal).setScale(4, BigDecimal.ROUND_HALF_UP);
            }
            priceValueOrg.setPrice(price);
            priceValueOrg.setPriceSold(price);
        }else{
            //低总价(底价总价)=房间表的底价总价
            priceValueOrg.setPrice(room.getDjTotal()==null?BigDecimal.ZERO:room.getDjTotal());
        }

        priceValueOrg.setIsSplit(IsSplitEnum.NO.getKey());
        priceValueOrg.setIsDelete(IsDeleteEnum.NO.getKey());
        priceValueOrg.setCreateTime(now);
        return priceValueOrg;
    }

    /**
     * 方法描述：将double转成BigDecimal向除
     * @param money 被除数
     * @param price 除数
     * 创建人：yang
     * 创建时间：2017年3月15日 下午3:13:03
     */
    public BigDecimal bigDecimalDIV(BigDecimal money, BigDecimal price) {

        if(price.equals(BigDecimal.ZERO)){
            return BigDecimal.ZERO;
        }

        BigDecimal b1 = money.setScale(4, BigDecimal.ROUND_HALF_UP);;
        BigDecimal b2 = price.setScale(4, BigDecimal.ROUND_HALF_UP);;
        BigDecimal doubleValue = b1.divide(b2, 4, RoundingMode.HALF_UP);

        return doubleValue;
    }

    @DS("mymrooms")
	@Override
	public List<MymRooms> selectAllRoomsFromMym(int month) {
		return mymRoomsMapper.selectAllRoomsFromMym(month);
	}

	@Override
	public void insertRoomsList(List<MymRooms> list) {
		mymRoomsMapper.insertRoomsList(list);
	}
}
